/*
	xmlParser.h
	--------------------
	
	Author: Olivier Sputael
	
	This file is the header of the class that will parse a xml file.
*/

#ifndef _XMLPARSER_H_
#define _XMLPARSER_H_

#include <iostream>
#include <vector>

#include <sl/sldefine.hxx>
#include <sl/dslinter.hxx>

#include <libxml/xmlreader.h>

#define 	XML_OPENING_TAG 	1
#define		XML_TEXT			3
#define		XML_CLOSING_TAG		15

using namespace std;

typedef struct {
	int opcode;
	char opcode_txt[32];
	int start_line_1;
	int start_line_2;
	int end_line_1;
	int end_line_2;
	int begin_pos_1;
	int begin_pos_2;
	int end_pos_1;
	int end_pos_2;
	char comment[MAX_DSL_COMMENT_SIZE+1];
} PARSED_HEADER_STRUCT;

typedef struct {
	unsigned long chan_id;
	unsigned long speed;
	unsigned long color;
	char name[SL_MAX_IDENTIFIER_LEN];
	char phys_chan[SL_MAX_IDENTIFIER_LEN];
	char prot_name[SL_MAX_IDENTIFIER_LEN];
	char params[SL_MAX_IDENTIFIER_LEN];
} PARSED_CHANNEL_STRUCT;

typedef struct {
	unsigned long id;
	unsigned long type_id;
	char name[SL_MAX_IDENTIFIER_LEN];
	int opcode;
} PARSED_TYPE_FIELD_STRUCT;

typedef struct {
	unsigned long type;
	char name[SL_MAX_IDENTIFIER_LEN];
	int kind;
	int kind_of_simple_type;
	unsigned long count;
	vector<PARSED_TYPE_FIELD_STRUCT> fields;
	unsigned long elt_id;
	unsigned long from;
	unsigned long till;
} PARSED_TYPE_STRUCT;

typedef struct {
	char name[SL_MAX_IDENTIFIER_LEN];
	unsigned long type_id;
	unsigned long var_id;
	unsigned long father_id;
	unsigned long elt_from_father;
	int driver_id;
	int channel_id;
	int in_or_out;
	int scope_type;
	int dsl_color;
	char address[16];
} PARSED_VAR_STRUCT;

typedef struct {
	char name[SL_MAX_IDENTIFIER_LEN];
	unsigned long id;
	unsigned long type_id;
	int argument_count;
} PARSED_METHODS_STRUCT;

typedef struct {
	char name[SL_MAX_IDENTIFIER_LEN];
	int async;
} PARSED_SEQUENCE_STRUCT;

typedef struct {
	int node_id;
	int from;
	int to;
} PARSED_CASE_STRUCT;

typedef struct {
	int id;
	unsigned long method_id;
	int is_launch;
	int param_count;
	vector<int> nodes;
	vector<PARSED_CASE_STRUCT> cases;
	int arg_count;
} PARSED_INSTR_STRUCT;

typedef struct {
	int id;
	int operator_id;
	int stack_offset;
	char func_name[SL_MAX_IDENTIFIER_LEN];
	int func_res_type;
	int func_param_count;
	int field_id;
	char* values;
	int length;
	unsigned long var_id;
} PARSED_OP_STRUCT;

typedef struct {
	int cfg_id;
	int kind_of_cfg;
	unsigned long self_var_id;
	char name[SL_MAX_IDENTIFIER_LEN];
} PARSED_STMTS_STRUCT;


class XmlParser {
public: 
	XmlParser (const char*);
	~XmlParser ();
	
	void 				endParsing ();
	bool 				xml_read_tag (char*);
	char* 				get_read_tag ();
	bool				is_empty_elt ();
	int					get_node_type ();
	bool				end_tag_read ();
	bool				header_tag_read ();
	
	void				parse_xml_header (PARSED_HEADER_STRUCT&);
	void				parse_xml_program (char[SL_MAX_IDENTIFIER_LEN]);
	void				parse_xml_channel (PARSED_CHANNEL_STRUCT&);
	void				parse_xml_types (PARSED_TYPE_STRUCT&);
	void				parse_xml_simple_type (PARSED_TYPE_STRUCT&);
	void				parse_xml_pointer_derived (PARSED_TYPE_STRUCT&);
	void				parse_xml_structure (PARSED_TYPE_STRUCT&);
	void				parse_xml_array (PARSED_TYPE_STRUCT&);
	void				parse_xml_list (PARSED_TYPE_STRUCT&);
	void				parse_xml_vars (PARSED_VAR_STRUCT&);
	void				parse_xml_node (unsigned long&);
	void				parse_xml_forward_method (PARSED_METHODS_STRUCT&);
	void				parse_xml_method (PARSED_METHODS_STRUCT&);
	void				parse_xml_methods (PARSED_METHODS_STRUCT&);
	void				parse_xml_sequence (PARSED_SEQUENCE_STRUCT&);
	void				parse_xml_instr (PARSED_INSTR_STRUCT&);
	void				parse_xml_operation (PARSED_OP_STRUCT&);
	void				parse_xml_instr_method_call (PARSED_INSTR_STRUCT&);
	void				parse_xml_instr_node (PARSED_INSTR_STRUCT&, int);
	void				parse_xml_instr_print (PARSED_INSTR_STRUCT&);
	void				parse_xml_instr_plugin (char[SL_MAX_IDENTIFIER_LEN]);
	void				parse_xml_instr_case_statement (PARSED_INSTR_STRUCT&);
	void				parse_xml_op_var (PARSED_OP_STRUCT&);
	void				parse_xml_op_operator (PARSED_OP_STRUCT&);
	void				parse_xml_op_constant (PARSED_OP_STRUCT&);
	void				parse_xml_op_stack (PARSED_OP_STRUCT&);
	void				parse_xml_op_field (PARSED_OP_STRUCT&);
	void				parse_xml_op_function (PARSED_OP_STRUCT&);
	void				parse_xml_stmts (PARSED_STMTS_STRUCT&);
	PARSED_CASE_STRUCT	parse_xml_case ();
private:
	bool read_next (char*);
	
	xmlTextReaderPtr reader;
};

#endif
